import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:gameplay_flutter/lib_runtime/extension/string_extension/string_text.dart';
import 'package:gameplay_flutter/m_me/constants/me_assets_constants.dart';
import 'package:gameplay_flutter/resource/language/generated/l10n.dart';
import 'package:get/get.dart';
import 'package:ones/ui.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

import '../me_controller.dart';
import 'recording_status.dart';

class AudioRecorder extends StatefulWidget {
  const AudioRecorder({Key? key}) : super(key: key);

  @override
  _AudioRecorderState createState() => _AudioRecorderState();
}

class _AudioRecorderState extends State<AudioRecorder> {
  late final MeController meController;
  final _audioRecorder = FlutterSoundRecorder();
  final _audioPlayer = FlutterSoundPlayer();

  Codec _codec = Codec.aacMP4;
  String msg = T.current.c_hold_to_talk;
  int seconds = 0;
  RecordingStatus recordingStatus = RecordingStatus.readyToRecord;
  Timer? _recordingTimer;
  Timer? _playbackTimer;
  String? _recordingFilePath;

  @override
  void initState() {
    super.initState();
    meController = Get.put(MeController());
    openTheRecorder();
    _audioPlayer.openPlayer();
  }

  @override
  void dispose() {
    _recordingTimer?.cancel();
    _playbackTimer?.cancel();
    super.dispose();
    _audioRecorder.closeRecorder();
    _audioPlayer.closePlayer();
  }

  Future<void> openTheRecorder() async {
    if (!kIsWeb) {
      var status = await Permission.microphone.request();
      if (status != PermissionStatus.granted) {
        throw RecordingPermissionException('Microphone permission not granted');
      }
    }
    await _audioRecorder!.openRecorder();
  }

  Future<void> record() async {
    try {
      await openTheRecorder();
      final directory = await getTemporaryDirectory();
      _recordingFilePath =
          '${directory.path}/recording_${DateTime.now().millisecondsSinceEpoch}.aac';

      await _audioRecorder.startRecorder(
        toFile: _recordingFilePath,
        codec: Codec.aacADTS,
      );
      setState(() {
        recordingStatus = RecordingStatus.recording;
      });

      _recordingTimer = Timer.periodic(Duration(seconds: 1), (timer) {
        setState(() {
          seconds++;
        });
        if (seconds >= 30) {
          stopRecorder();
          timer.cancel();
        }
      });
    } catch (e) {
      EasyLoading.showToast(e.toString());
    }
  }

  Future<void> stopRecorder() async {
    try {
      _recordingTimer?.cancel();
      await _audioRecorder.stopRecorder();
      if (seconds < 5) {
        EasyLoading.showToast('录音过短');
        setState(() {
          recordingStatus = RecordingStatus.readyToRecord;
          seconds = 0;
        });
      } else {
        setState(() {
          recordingStatus = RecordingStatus.readyToPlay;
        });
      }
    } catch (e) {
      EasyLoading.showToast(e.toString());
    }
  }

  void playRecording() async {
    if (_recordingFilePath != null) {
      await _audioPlayer.startPlayer(
        fromURI: _recordingFilePath,
        codec: Codec.aacADTS,
        whenFinished: () {
          setState(() {
            recordingStatus = RecordingStatus.readyToPlay;
            _playbackTimer?.cancel();
            seconds = 0;
          });
        },
      );
      setState(() {
        recordingStatus = RecordingStatus.playing;
        seconds = 0;
      });

      _playbackTimer = Timer.periodic(Duration(seconds: 1), (timer) {
        setState(() {
          seconds++;
        });
      });
    }
  }

  void pauseRecording() async {
    await _audioPlayer.stopPlayer();
    setState(() {
      recordingStatus = RecordingStatus.readyToPlay;
      _playbackTimer?.cancel();
      seconds = 0;
    });
  }

  void resetRecording() {
    setState(() {
      recordingStatus = RecordingStatus.readyToRecord;
      seconds = 0;
    });
  }

  void uploadRecording() {
    // 上传录音逻辑
    if (_recordingFilePath != null) {
      meController
          .uploadFile(File(_recordingFilePath!), "audio", "myViceo", seconds)
          .then((value) {
        _dialogToast("Successfully updated");
        Navigator.pop(context);
      });
    }
  }

  _dialogToast(String msg) {
    Fluttertoast.showToast(
        msg: msg,
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIosWeb: 1,
        backgroundColor: Color(0x4D000000),
        textColor: Colors.white,
        fontSize: 16.0);
  }

  @override
  Widget build(BuildContext context) {
    var _iconRecord = MeAssetsConstants.iconRecord;
    switch (recordingStatus) {
      case RecordingStatus.readyToRecord:
        _iconRecord = MeAssetsConstants.iconRecord;
        break;
      case RecordingStatus.recording:
        _iconRecord = MeAssetsConstants.iconRecord1;
        break;
      case RecordingStatus.readyToPlay:
        _iconRecord = MeAssetsConstants.iconRecordPlay;
        break;
      case RecordingStatus.playing:
        _iconRecord = MeAssetsConstants.iconPause;
        break;
    }
    return Container(
        child: Column(mainAxisSize: MainAxisSize.min, children: [
      SizedBox(height: 25.h),
      Stack(
        children: [
          Center(
            child: T.current.m13_my_voice.text(
                fontSize: 22.sp,
                color: const Color(0xFF1B1B1B),
                weight: TextFontWeight.medium),
          ),
          Padding(
            padding: EdgeInsetsDirectional.only(start: 23.w, top: 2.h),
            child: T.current.me_edit_cancel.text(
              fontSize: 18.sp,
              color: const Color(0xFFA8A8A8),
              weight: TextFontWeight.regular,
            ),
          ).onClick(() {
            Navigator.pop(context);
          })
        ],
      ),
      SizedBox(height: 25.h),
      Row(mainAxisSize: MainAxisSize.min, children: [
        Image.asset(
          MeAssetsConstants.iconRecording,
          width: 32.w,
          height: 32.h,
        ),
        SizedBox(
          width: 11.w,
        ),
        Text("00:$seconds",
            style: TextStyle(
                fontSize: 20.sp,
                color: const Color(0xFF444444),
                fontWeight: FontWeight.normal)),
        SizedBox(width: 11.w),
        Image.asset(
          MeAssetsConstants.iconRecording,
          width: 32.w,
          height: 32.h,
        ),
      ]),
      SizedBox(height: 10.h),
      T.current.m15_recording_time_tips.text(
          fontSize: 14.sp,
          color: const Color(0xFFC1C1C1),
          weight: TextFontWeight.regular),
      SizedBox(height: 10.h),
      Row(mainAxisSize: MainAxisSize.min, children: [
        if (recordingStatus == RecordingStatus.readyToPlay)
          Image.asset(
            MeAssetsConstants.iconRecordAfresh,
            width: 30.w,
            height: 30.h,
          ).onClick(() {
            resetRecording();
          }),
        SizedBox(width: 51.w),
        GestureDetector(
            onLongPressStart: (details) {
              record();
            },
            onLongPressEnd: (details) {
              stopRecorder();
            },
            onLongPressMoveUpdate: (details) {
              if (details.globalPosition.dx < 0 ||
                  details.globalPosition.dx >
                      MediaQuery.of(context).size.width) {
                stopRecorder();
              }
            },
            onTap: () {
              if (recordingStatus == RecordingStatus.readyToPlay) {
                playRecording();
              } else if (recordingStatus == RecordingStatus.playing) {
                pauseRecording();
              }
            },
            child: Image.asset(
              _iconRecord,
              width: 78.w,
              height: 78.h,
            )),
        SizedBox(width: 51.w),
        if (recordingStatus == RecordingStatus.readyToPlay)
          Image.asset(
            MeAssetsConstants.iconRecordFinish,
            width: 30.w,
            height: 30.h,
          ).onClick(() {
            uploadRecording();
          }),
      ]),
      SizedBox(height: 10.h),
      if (recordingStatus == RecordingStatus.readyToRecord)
        T.current.m15_hold_record.text(
            fontSize: 14.sp,
            color: const Color(0xFFC1C1C1),
            weight: TextFontWeight.regular)
      else if (recordingStatus == RecordingStatus.recording)
        T.current.m15_slide_cancel.text(
            fontSize: 14.sp,
            color: const Color(0xFFC1C1C1),
            weight: TextFontWeight.regular)
      else if (recordingStatus == RecordingStatus.readyToPlay)
        T.current.m15_click_pause.text(
            fontSize: 14.sp,
            color: const Color(0xFFC1C1C1),
            weight: TextFontWeight.regular)
      else if (recordingStatus == RecordingStatus.playing)
        T.current.m15_click_to_play.text(
            fontSize: 14.sp,
            color: const Color(0xFFC1C1C1),
            weight: TextFontWeight.regular),
      SizedBox(height: 54.h),
    ]));
  }
}
